#ifndef KERNEL_UTILS_STRING_H
#define KERNEL_UTILS_STRING_H

#include <Mint/Types.h>
#include <Mint/Errors.h>
#include "Utils/Character.h"

class CString
{
public:
	CString();
	CString( const CString & string );
	CString( const char * string, bool adopt = false );
	CString( const char * string, Size length, bool adopt = false );
	~CString();

	CString & SetTo( const char * string, bool adopt = false );
	CString & SetTo( const char * string, Size length, bool adopt = false );

	void Adopt( const char * string );
	void Adopt( const char * string, Size length );

	Result Append( CString * string );
	Result Append( const char * string );
	Result Append( const char * string, Size length );

	Result Remove( Size start );
	Result Remove( Size start, Size length );

	CString * SubString( Size start );
	CString * SubString( Size start, Size length );

	CString * Clone( void );
	static char * Clone( const char * string );
	static char * Clone( const char * string, Size length, Size size = 0 );

	bool Contains( const CString & string, bool ignoreCase = false );
	bool Contains( const char * string, Size length, bool ignoreCase = false );

	int Compare( const CString & string, bool ignoreCase = false );
	int Compare( const char * string, bool ignoreCase = false );
	int Compare( const char * string, Size length, bool ignoreCase = false );
	int CompareOrdinal( const CString & string, bool ignoreCase = false );
	int CompareOrdinal( const char * string, bool ignoreCase = false );
	int CompareOrdinal( const char * string, Size length, bool ignoreCase = false );

	static int Compare( const char * left, Size leftLength, const char * right, Size rightLength, bool ignoreCase = false );
	static int CompareOrdinal( const char * left, Size leftLength, const char * right, Size rightLength, bool ignoreCase = false );

	const char * ToCharArray( void ) { return fData; }
	Size Length( void ) { return fLength; }

	static Size Length( const char * string );

	const int32 ToInt32( void );
	static const int32 ParseInt32( const char * value );
	static const int32 ParseInt32( const char * value, Size length );

	CString & FromFormat( const char * format, ... );
	CString & FromFormat( const char * format, Size length, ... );
	static const char * Format( const char * format, ... );
	static const char * Format( const char * format, Size length, ... );

private:
	static Size _ParseFormatFlags( const char * string, uint32 * flags, uint8 * base, uint32 * width, char ** prefix );
	static Size _FormatInteger( char ** result, Size length, int value, uint32 flags = 0, uint8 base = 10, uint32 width = 0, char * prefx = NULL );
	static Size _FormatString( char ** result, Size length, const char * value, uint32 flags = 0, uint32 width = 0 );

private:
	char * fData;
	Size fSize;
	Size fLength;
};

enum
{
	STRING_FORMAT_RIGHT_JUSTIFIED	= 0x0001,
	STRING_FORMAT_SHOW_SIGN			= 0x0002,
	STRING_FORMAT_ZERO_PADDED		= 0x0004,
	STRING_FORMAT_PREPEND			= 0x0008,
	STRING_FORMAT_UPPER_CASE		= 0x0010,
	STRING_FORMAT_SIGNED			= 0x0020,
	STRING_FORMAT_INTEGER			= 0x0040,
	STRING_FORMAT_CHARACTER			= 0x0080,
	STRING_FORMAT_STRING			= 0x0100,
};

#endif // KERNEL_UTILS_STRING_H
